home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 140 / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin / tools / dshell / dsh333bs.lzh / dtype.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-28  |  16.1 KB  |  816 lines

  1. /*
  2.     dshell    v3
  3.  
  4.     コマンド行(◎... TYPE=~)の処理
  5. */
  6.  
  7. #include    "dsh.h"
  8.  
  9. static void *get_copywk(int *, int);
  10. static void copy(const uchar *, const uchar *, char);
  11. static int prepx(uchar *, uchar *);
  12. static int postx(uchar *);
  13. static int chk_drvready(char, const char *);
  14.  
  15.  
  16. /*
  17.     キャラクタデバイスかどうかの確認
  18. */
  19. uchar
  20. isDevice(const char *s)
  21. {
  22.     int fno, stat;
  23.  
  24.     if ((fno = OPEN(s, 0)) < 0)
  25.         return FALSE;
  26.     stat = IOCTRLGT(fno);
  27.     CLOSE(fno);
  28.  
  29.     return (stat >= 0 && (stat & 0x80));
  30. }
  31.  
  32.  
  33. /*
  34.     スクロール範囲の左上ドット座標を得る
  35. */
  36. unsigned long getConHome(void)
  37. {
  38.     unsigned long n;
  39.  
  40.     asm("
  41.         moveq.l    #-1,d1
  42.         moveq.l    #-1,d2
  43.         moveq.l    #$2e,d0    ;_B_CONSOL
  44.         trap    #15
  45.         move.l    d1,%0
  46.     " : "=g"(n) : : "d0", "d1", "d2");
  47.  
  48.     return n;
  49. }
  50.  
  51.  
  52. /*
  53.     TYPE= よりあとの文字列をコマンドとして解釈・実行
  54.     datは TYPE=よりあとを指している
  55.         例:    TYPE=DOC:SAMPLE.DOC
  56.                  ^
  57.               datの指している位置
  58. */
  59. static short defG;
  60.  
  61. void 
  62. dtype(const uchar *dat, uchar inMenuFlag)
  63. {
  64.     uchar *temp;
  65.     uchar *prbf;        /* 後処理用情報バッファ */
  66.     static const char GMDSW[] = {'-', '+', '*', '?', };    /* 画面モード切替マーク */
  67.     short g, gm = -1;        /* gm:GMODE変化フラグ(変化前保存兼用) */
  68.     uchar noUpdateScreen = FALSE;
  69.     unsigned long typeCommand;
  70.     ushort dexecFlag = 0;
  71.     uchar *p, *q, c;
  72.     uchar f;
  73.     int n;
  74.  
  75.     p = (uchar *)&typeCommand;
  76.     q = dat;
  77.     *p++ = 0;
  78.     *p++ = (*q++ & ~0x20);
  79.     *p++ = (*q++ & ~0x20);
  80.     *p = (*q++ & ~0x20);
  81.     q++;    // skip ':'
  82.  
  83.     prbf = NULL;
  84.     if (dat[3] == ';' || dat[3] == ',') {
  85.         long n;
  86.  
  87.         prbf = malloc(POSPMAX);
  88.         if (prbf == NULL) {
  89.             d_heap();
  90.             goto SKIP;
  91.         }
  92.         n = prepx(q, prbf);
  93.         if (n <= 0) {
  94.             free(prbf);
  95.             prbf = NULL;
  96.             if (n < 0)
  97.                 goto SKIP;    /* 前処理がエラーだった場合、以降の処理を行なわない */
  98.         }
  99.         q += n;    /* 前処理を行ない、前処理部分をスキップする */
  100.     }
  101.  
  102.     defG = defGMODE;
  103.     g = -1;
  104.     if (*(q + 1) == ':') {
  105.         g = sizeof(GMDSW) / sizeof(GMDSW[0]);
  106.         while (--g >= 0) {
  107.             if (*q == GMDSW[g]) {
  108.                 if (g > 2) {
  109.                     if (defG == 0) {
  110.                         gm = 0;
  111.                         defG++;
  112.                     }
  113.                     dexecFlag |= DEX_GMODE | DEX_GCLS | DEX_NDIN;    ///
  114.                 } else if (GMODE != g) {
  115.                     gm = GMODE;
  116.                     set_g_mode(g);
  117.                     dexecFlag |= DEX_NDIN;
  118.                 }
  119.                 q += 2;
  120.                 break;
  121.             }
  122.         }
  123.     }
  124.     if (g < 0 && defG != 0)
  125.         dexecFlag |= DEX_GMODE;
  126.     q += strspn(q, " \t");
  127.  
  128.     switch (typeCommand) {
  129.     case 'EDE':
  130.         /*
  131.             作業用メモリを確保
  132.         */
  133.         temp = malloc(strlen(q) + 1);
  134.         if (temp == NULL) {
  135.             d_heap();
  136.             break;
  137.         }
  138.  
  139.         /*
  140.             前半のEXE部分
  141.         */
  142.         dexecFlag |= DEX_SHELL;
  143.         p = temp;
  144.         if (*q == '!') {
  145.             *p++ = *q++;
  146.             dexecFlag |= (DEX_SLNT | DEX_NDIN);
  147.         }
  148.         q += strspn(q, " \t");
  149.         f = FALSE;
  150.         while ((c = *q++) != '\0' && c != ';') {
  151.             *p++ = c;
  152.             if (c != ' ' && c != '\t')
  153.                 f = TRUE;
  154.         }
  155.         *p = '\0';
  156.         if (c == '\0')
  157.             q--;
  158.         q += strspn(q, " \t");
  159.         if (*q == '\0' || *q == ';' && *(q + 1) == '\0') {
  160.             q = temp;
  161.             goto postExe;
  162.         }
  163.         if (f) {        /* "COMMAND.X" のみなら呼出をパス */
  164.             dexecFlag = dexec(temp, dexecFlag);
  165.             if (GMODE > 0 && (dexecFlag & DEX_NDIN))
  166.                 g_push(TRUE);
  167.         } else if (gm >= 0)
  168.             din(FALSE);
  169.  
  170.         /*
  171.             真中のDOC部分
  172.         */
  173.         p = temp;
  174.         while ((c = *q++) != '\0' && c != ';')
  175.             *p++ = c;
  176.         *p = '\0';
  177.         if (c == '\0')
  178.             q--;
  179.         q += strspn(q, " \t");
  180.         if (*temp != '\0') {
  181.             temp = realloc(temp, strlen(temp) + 1);
  182.             dshell(temp);
  183.         }
  184.  
  185.         /*
  186.             後半のEXE部分
  187.         */
  188.         dexecFlag &= ~(DEX_SLNT | DEX_NDIN);
  189.         if (gm >= 0)
  190.             dexecFlag |= DEX_NDIN;
  191.         p = q;
  192.         if (*p == '!') {
  193.             dexecFlag |= (DEX_SLNT | DEX_NDIN);
  194.             p++;
  195.         }
  196.         p += strspn(p, " \t");
  197.         f = *p;
  198. postExe:
  199.         if (f)
  200.             dexecFlag = dexec(q, dexecFlag);
  201.         free(temp);
  202.         break;
  203.     case 'DOC':
  204.         dexecFlag = 0;
  205.         if (gm >= 0)
  206.             din(FALSE);
  207.         dshell(q);
  208.         break;
  209.     case 'EXE':
  210.         dexecFlag = dexec(q, dexecFlag | DEX_WAIT);
  211.         break;
  212.     case 'CLI':
  213.         dexecFlag = dexec(q, dexecFlag | DEX_WAIT | DEX_SHELL);
  214.         break;
  215.     case 'EXS':
  216.         dexecFlag = dexec(q, dexecFlag | DEX_NCLR);
  217.         break;
  218.     case 'COP':
  219.         dexecFlag = 0;
  220.         if (n = dinstrchr(q, ' ')) {
  221.             p = q + n - 1;
  222.             *p++ = '\0';
  223.             copy(q, p, TRUE);
  224.             *--p = ' ';
  225.         } else {
  226.             dabort("コピーのパラメータが異常です");
  227.         }
  228.         noUpdateScreen = TRUE;
  229.         break;
  230.     case 'END':
  231.         setenv_and_export("DSHELLSTAT", q);
  232.         dend();
  233.         break;
  234.     default:
  235.         n = (typeCommand << 8);
  236. #define    deviceName    ((uchar *)&n)
  237.         dexecFlag = 0;
  238.         if (isDevice(deviceName)) {
  239.             noUpdateScreen = TRUE;
  240.             if (typeCommand == 'PCM' || typeCommand == 'OPM') {
  241.                 if (!inMenuFlag)
  242.                     p_execmark(L'♪');
  243.                 if (typeCommand == 'PCM') {
  244.                     copy(q, deviceName, FALSE);
  245.                     if (debugMode && (B_SFTSNS() & (LED_CODEIN | LED_KANA)) == LED_CODEIN)
  246.                         w_wait(99);
  247.                 } else {
  248.                     copy(q, deviceName, TRUE);
  249.                     if (debugMode && (B_SFTSNS() & (LED_CODEIN | LED_KANA)) == LED_CODEIN) {
  250.                         w_wait(99);
  251.                         w_wait(99);
  252.                     }
  253.                 }
  254.             } else {
  255.                 copy(q, deviceName, TRUE);
  256.             }
  257.         } else {
  258.             dabort("指定のデバイスが組み込まれていません");
  259.         }
  260.         break;
  261. #undef    deviceName
  262.     }
  263.  
  264.     if (gm >= 0 && (gm == 0 || GMODE == 0)) {
  265.         set_g_mode(gm);
  266.         din(FALSE);
  267.         noUpdateScreen = FALSE;
  268.     } else if (GMODE > 0 && (dexecFlag & DEX_NDIN)) {
  269.         g_push(TRUE);
  270.     }
  271.     if (GMODE == 0 && resetBgFlag)
  272.         resetBG();
  273.     resetBgFlag = FALSE;
  274.     if (!noUpdateScreen) {
  275.         p_scr();
  276.         p_fpt(1);
  277.         p_time(1);
  278.     }
  279.  
  280. SKIP:
  281.     if (prbf != NULL) {        /* 前処理したなら後処理もする */
  282.         postx(prbf);
  283.         free(prbf);
  284.     }
  285.     w_close();
  286. }
  287.  
  288.  
  289. /*
  290.     外部プログラムを子プロセスとして起動
  291.  
  292.     DEX_WAIT = 実行後、確認のクリックを要求する
  293.     DEX_PSCR = 実行後、画面を描き直す
  294.     DEX_FKON = 実行の間、ファンクション行を有効にする
  295.     DEX_RETM = 実行前、「exit で戻る」旨を表示
  296.     DEX_NCLR = 実行前に、画面を初期化しない
  297.     DEX_NDOUT = DEX_NCLR に同じ
  298.     DEX_NDIN = 実行後に、画面を初期化しない
  299.     DEX_SLNT = コンソールを表示範囲外に切って実行する (DEX_NDOUT の意味を兼ねる)
  300.     DEX_GCLS = 画面を65536色モードに初期化のうえ、クリアする
  301.     DEX_SHELL = COMMAND.X を介して実行する
  302. */
  303. ushort
  304. dexec(const uchar *command, ushort flag)
  305. {
  306.     static const uchar childShell[] = "COMMAND.X";
  307.     uchar file[300];
  308.     struct COMLINE comlin;
  309.     int adr, mx, my;
  310.     short breakckMod;
  311.     short shiftKeys = 0;
  312.     static uchar scrnMode[] = { 16, 12, 12, };
  313.     char curdirBak[70];
  314.  
  315.     w_open();
  316.     w_load();
  317.  
  318.     if (*command == '!') {
  319.         command++;
  320.         flag |= DEX_SLNT;
  321.     }
  322.     file[255] = '\0';
  323.     if (flag & DEX_SHELL) {
  324.         strcpy(file, childShell);
  325.         strcpy(file + sizeof(childShell) - 1, " ");
  326.         strncpy(file + sizeof(childShell), command, sizeof(file) - sizeof(childShell));
  327.     } else {
  328.         strncpy(file, command, sizeof(file));
  329.     }
  330.     if (file[255] != '\0')    // command が長すぎる
  331.         file[0] = '\0';
  332.  
  333.     if (PATHCHK(file, &comlin, NULL) < 0) {
  334.         dabort("実行ファイルが見当たりません");
  335.         din(TRUE);
  336.         return flag;
  337.     }
  338.     adr = LOAD(file, &comlin, NULL);
  339.     if (adr < 0) {
  340.         dabort("ファイルが見つかりません");
  341.         din(TRUE);
  342.         return flag;
  343.     }
  344.  
  345.     shiftKeys = B_SFTSNS();
  346.     mspos(&mx, &my);
  347.     mouse(2);
  348.     breakckMod = BREAKCK(-1);
  349.     LEDMOD(0, 0);    // かなキー OFF
  350.     LEDMOD(1, 0);    // ローマ字キー OFF
  351.     LEDMOD(2, 0);    // コード入力キー OFF
  352.     LEDMOD(6, 0);    // 全角キー OFF
  353.     getcwd(curdirBak, sizeof(curdirBak));
  354.  
  355.     if (flag & DEX_GCLS) {
  356.         vsync();
  357.         B_WPOKE(VIDEOR2, 0);
  358.         C_WIDTH(5);
  359.     }
  360.  
  361.     if (flag & DEX_SLNT) {
  362.         B_CONSOL(0, 512, 96 - 1, 31 - 1);
  363.         BREAKCK(0);    // Human68k v1.xx の場合は break off 止まり
  364.         BREAKCK(2);    // v2.xx 以降の場合は break kill
  365.     } else {
  366.         uchar crtmod = CRTMOD(-1);
  367.  
  368.         B_CONSOL(0, 0, (crtmod == 12) ? 64 - 1 : 96 - 1, 32 - 1);
  369.         if (!(flag & DEX_NCLR)) {
  370.             dout();
  371.             if (crtmod == 12) {
  372.                 vsync();
  373.                 B_WPOKE(VIDEOR2, 0x1d2f);    /* 半透明 TX & GR */
  374.             }
  375.         }
  376.         if (flag & DEX_FKON)
  377.             nouse_fnk();
  378.     }
  379.     if (flag & DEX_RETM)
  380.         B_PRINT("\r\n exit コマンドでDSHELLに戻ります.\r\n");
  381.  
  382.     clr_kbf();
  383.     B_PRINT("");
  384.     B_CUROFF();    // 'B'_CUROFF で間違いありません
  385.     EXECONLY(adr);
  386.     B_WPOKE(CRTCR21, 0x0033);    // jpeged.r 対策...
  387.     B_PRINT("");
  388.  
  389.     mouse(4);
  390.     OS_CUROF();
  391.     initKeyBuffer();
  392.     BREAKCK(breakckMod);
  393.     noSetIbitFlag = FALSE;
  394.     if (debugMode) {
  395.         if (shiftKeys & LED_CODEIN) {
  396.             LEDMOD(2, !(codein_on()));
  397.             if (shiftKeys & LED_KANA)
  398.                 LEDMOD(0, 1);
  399.             if (shiftKeys & LED_ROMA)
  400.                 LEDMOD(1, 1);
  401.             if (shiftKeys & LED_INS)
  402.                 LEDMOD(4, 1);
  403.         }
  404.         if (shiftKeys & LED_ZENKAKU)
  405.             LEDMOD(6, 1);
  406.     }
  407.     CHGDRV((*curdirBak & 0x1f) - 1);
  408.     CHDIR(curdirBak + 2);
  409.  
  410.     if (flag & DEX_WAIT) {
  411.         if ((ushort)getConHome() >= 512 - 16) {
  412.             B_CONSOL(0, 16, 128 - 1, 30 - 1);
  413.             cls();
  414.         }
  415.         w_wait2();
  416.     }
  417.  
  418.     if (flag & DEX_GMODE) {
  419.         ushort r20 = B_WPEEK(CRTCR20);
  420.  
  421.         switch (r20) {
  422.         case 0x300:
  423.         case 0x301:
  424.         case 0x305:
  425.         case 0x310:
  426.         case 0x311:
  427.         case 0x315:
  428.             GMODE = 1;
  429.             break;
  430.         case 0x316:
  431.             GMODE = 2;
  432.             break;
  433.         default:
  434.             GMODE = defG;
  435.             break;
  436.         }
  437.     }
  438.  
  439.     use_fnk();
  440.     if (!(flag & DEX_NDIN) || (uchar)(CRTMOD(-1)) != scrnMode[GMODE]) {
  441.         din(TRUE);
  442.         flag &= ~DEX_NDIN;
  443.     } else {
  444.         mouse(0);
  445.         mouse(4);
  446.         B_COLOR(3);
  447.         B_CONSOL(0, 0, 128 - 1, 64 - 1);
  448.         initPalet();
  449.         clr_kbf();
  450.     }
  451.     msarea(0, 0, GWIDTH - 1, 511);
  452.     setmspos(mx, my);
  453.  
  454.     if (flag & DEX_PSCR) {
  455.         p_scr();
  456.         p_fpt(1);
  457.         p_time(1);
  458.     }
  459.  
  460.     return flag;
  461. }
  462.  
  463.  
  464. /*
  465.     copy():コピーのためのワークを確保(MALLOC())
  466. */
  467. static void *
  468. get_copywk(int *mem, int flen)
  469. {
  470.     int p;
  471.  
  472.     *mem = flen;
  473.     p = MALLOC(*mem);
  474.     if (p > 0) {
  475.         return (void *)p;
  476.     }
  477.     *mem = 8*1024;
  478.     p = MALLOC(*mem);
  479.     if (p > 0) {
  480.         return (void *)p;
  481.     }
  482.     *mem = 1024;
  483.     p = MALLOC(*mem);
  484.     if (p > 0) {
  485.         return (void *)p;
  486.     }
  487.     return NULL;
  488. }
  489.  
  490. static void 
  491. copy(const uchar *file1, const uchar *file2, char winFlag)
  492. {
  493.     int fni, fno;
  494.     char *ptr;
  495.     int mem;
  496.     int flen;
  497.     int n, l;
  498.     int a;
  499.     int nf = 0;
  500.  
  501.     if (winFlag) {
  502.         w_open();
  503.         w_copy();
  504.     }
  505.     fni = open(file1, O_RDONLY | O_BINARY);
  506.     if (fni < 0) {
  507.         dabort("ファイルが見つかりません");
  508. //        w_close();
  509.         return;
  510.     }
  511.     if ((flen = dfilelength(fni)) < 0) {
  512.         dabort("ファイルの長さが得られません");
  513.         close(fni);
  514. //        w_close();
  515.         return;
  516.     }
  517.     fno = open(file2, O_WRONLY | O_BINARY | O_TRUNC);
  518.     if (fno < 0) {
  519.         fno = open(file2, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, O_RDWR);
  520.         if (fno < 0) {
  521.             dabort("コピー先がオープン出来ません");
  522.             close(fni);
  523. //            w_close();
  524.             return;
  525.         }
  526.     }
  527.     ptr = get_copywk(&mem, flen);
  528.     if (ptr == NULL) {
  529.         d_mem();
  530.         goto EXIT;    /* fclose()を一括する為ヨン */
  531.     }
  532.  
  533.     n = flen / mem;
  534.     l = flen % mem;
  535.     for (a = 0; a < n; a++) {
  536.         if (read(fni, ptr, mem) != mem) {
  537.             d_read();
  538.             nf = 1;
  539.             break;
  540.         }
  541.         if (write(fno, ptr, mem) != mem) {
  542.             d_write();
  543.             nf = 1;
  544.             break;
  545.         }
  546.     }
  547.     if (!nf & l) {
  548.         if (read(fni, ptr, l) != l) {
  549.             d_read();
  550.         } else if (write(fno, ptr, l) != l) {
  551.             d_write();
  552.         }
  553.     }
  554.     if (MFREE(ptr)) {
  555.         d_mfree();
  556.     }
  557.  
  558. EXIT:
  559.     close(fno);
  560.     close(fni);
  561. //    w_close();
  562. }
  563.  
  564.  
  565. /*
  566.     TYPE=xxx;~~:... の~~部分(前処理)を処理する
  567.     datp:    ~~ の先頭を指すポインタ
  568.     戻り値:    length("~~")+1 (戻り先でdatpに足すと':'の次からを指して都合いいので)
  569.         ただし戻り値が-1だった場合、エラーなので戻り先での処理は中断する。
  570.  
  571.  
  572.     (前処理のセパレータを '=' の他 ' ' も許すことにした)
  573.  
  574.     CD=xxx : 実行前にカレントパス移動。終了後パスを戻す。
  575.             xxx にドライブ指定があった場合、
  576.             カレントドライブ移動+パス移動、
  577.             後処理はパスを戻す+カレントドライブを戻す
  578.  
  579.         移動先のドライブがnot readyだった場合は待つ。
  580.             右クリックされたら待ち中止。
  581.  
  582.     CK=n    n = 'A' ~ 'Z'
  583.         そのドライブが準備OKかどうかチェックする。
  584.         準備できてない場合は待つ。
  585.             右クリックで中断。
  586.  
  587.  
  588.     posp[] に後処理のための情報を入れて戻す
  589.     (現時点では(ドライブ移動があれば移動前のドライブ名("A:"など)+)変更前のカレントパス)
  590.  
  591.     v3.30
  592.         CD= でも CK= でもなければ、CD= が省略されているものと見なすようにした
  593. */
  594. static int
  595. prepx(uchar *datp, uchar *posp)
  596. {
  597.     int len = -1;
  598.     uchar buffer[EXLEN];
  599.     uchar posp2[4];    // 'A:',0 が収まれば十分
  600.     uchar tmpbf[80];
  601.  
  602.     *posp = '\0';
  603.     *posp2 = '\0';
  604.  
  605.     if ((datp[0] | 0x20) == 'c' && (datp[1] | 0x20) == 'k'
  606.       && (datp[2] == '=' || datp[2] == ' ')) {
  607.         if (datp[4] == ':' && isalpha(datp[3])) {
  608.             len = 5;
  609.             if (chk_drvready(*(datp + 3), "CHECKDRV:")) {
  610.                 wait_mb_off();
  611.                 w_open();
  612.                 w_mes(0, "CHECKDRV:");
  613.                 w_mes(2, "処理を中断します");
  614.                 w_wait(150);
  615. //                w_close();
  616.                 goto ABORT;
  617.             }
  618.         }
  619.     } else {
  620.         uchar *bufp = buffer;
  621.         uchar *datpBak = datp;
  622.  
  623.         if ((datp[0] | 0x20) == 'c' && (datp[1] | 0x20) == 'd'
  624.           && (datp[2] == '=' || datp[2] == ' '))
  625.             datp += 3;
  626.         if (datp[1] == ':' && isalpha(datp[0])) {
  627.             int drv;
  628.             if (chk_drvready(*datp, "CHGDRV:")) {
  629.                 wait_mb_off();
  630.                 w_open();
  631.                 w_mes(0, "CHGDRV:");
  632.                 w_mes(2, "処理を中断します");
  633.                 w_wait(150);
  634. //                w_close();
  635.                 goto ABORT;
  636.             }
  637.             sprintf(posp2, "%c:", CURDRV() + 'A');    /* 後処理用に現ドライブを得る */
  638.             drv = (*datp & 0x1f) - 1;
  639.             if (CHGDRV(drv) < drv) {
  640.                 w_open();
  641.                 sprintf(tmpbf, "ドライブ %C: への移動に失敗しました", *datp);
  642.                 w_mes(0, "CHGDRV:");
  643.                 w_mes(1, tmpbf);
  644.                 w_mes(2, "処理を中断します");
  645.                 w_wait(200);
  646. //                w_close();
  647.                 *posp = '\0';
  648.                 goto ABORT;
  649.             }
  650.             *bufp++ = *datp++;
  651.             *bufp++ = *datp++;
  652.         }
  653.         len = dinstrchr(datp, ':');
  654.         if (len <= 0 || len > EXLEN - 3) {
  655.             w_open();
  656.             w_mes(0, "CHDIR:");
  657.             w_mes(1, "記述が異常です(':'が無い)");
  658.             w_mes(2, "処理を中断します");
  659.             w_wait(200);
  660. //            w_close();
  661.             goto ABORT;
  662.         }
  663.         strncpy(bufp, datp, len - 1);
  664.         *(bufp + len - 1) = '\0';
  665.         len += (datp - datpBak);
  666.  
  667.         w_open();
  668.         sprintf(tmpbf, "%s に移動します", buffer);
  669.         w_mes(0, "CHDIR:");
  670.         w_mes(1, tmpbf);
  671.         w_wait(20);    /* 最高0.2秒表示 */
  672. //        w_close();
  673.  
  674.         if (getcwd(posp, POSPMAX) == NULL) {
  675.             w_open();
  676.             w_mes(0, "エラー:dtype.c(POSPMAXの不足)");
  677.             w_wait(300);    /* 最高3秒待つ */
  678. //            w_close();
  679.             if (*posp2) {
  680.                 strcpy(posp, ".;");
  681.                 strcat(posp, posp2);
  682.             }
  683.             goto ABORT;
  684.         }
  685.         if (chdir(buffer)) {
  686.             w_open();
  687.             w_mes(0, "パスが移動できませんでした");
  688.             w_mes(2, "処理を中断します");
  689.             w_wait(100);    /* 最高1秒待つ */
  690. //            w_close();
  691.             if (*posp2) {
  692.                 strcpy(posp, ".;");
  693.                 strcat(posp, posp2);
  694.             }
  695.             goto ABORT;
  696.         }
  697.         if (*posp2) {
  698.             strcat(posp, ";");
  699.             strcat(posp, posp2);
  700.         }
  701. #if 0
  702.     } else {            /* default */
  703.         sprintf(tmpbf, "<%.*s>", strcspn(datp, ":"), datp);
  704.         w_open();
  705.         w_mes(0, "現在未対応の処理です");
  706.         w_mes(1, tmpbf);
  707.         w_mes(2, "なにもしないまま処理を続けます");
  708.         w_wait(200);    /* 最高2秒待つ */
  709. //        w_close();
  710.         *posp = '\0';
  711. #endif
  712.     }
  713.  
  714.     posp = realloc(posp, strlen(posp) + 1);
  715.     return len;
  716.  
  717. ABORT:
  718.     if (*posp != '\0')
  719.         postx(posp);
  720.     return -1;
  721. }
  722.  
  723. /*
  724.     後処理
  725.     今んとこ後処理の必要なprepxがchdrv・chdirだけなんで、
  726.     ここの処理もカレントドライブ・パスを戻すだけ
  727. */
  728. static int
  729. postx(uchar *posp)
  730. {
  731.     int sep, ret, drv;
  732.  
  733.     if (*posp == '\0') {
  734.         return 0;
  735.     }
  736.  
  737.     sep = dinstrchr(posp, ';');
  738.     if (sep) {
  739.         posp[sep - 1] = '\0';
  740.     }
  741.  
  742.     if (chdir(posp)) {
  743.         w_open();
  744.         w_mes(0, "カレントパスを戻せませんでした");
  745.         w_mes(2, "パスを戻さないまま処理を続けます");
  746.         w_wait(300);    /* 最高3秒待つ */
  747. //        w_close();
  748.         ret = -1;
  749.     } else {
  750. #if 0
  751.         w_open();
  752.         w_mes(0, "CHDIR:");
  753.         w_mes(1, "パスを移動前に戻しました");
  754.         w_wait(20);    /* 0.2秒表示 */
  755. //        w_close();
  756. #endif
  757.         ret = 0;
  758.     }
  759.  
  760.     if (sep) {
  761.         drv = (posp[sep] & 0x1f) - 1;
  762.         if (CHGDRV(drv) < drv) {
  763.             w_open();
  764.             w_mes(0, "カレントドライブを戻せませんでした");
  765.             w_mes(2, "ドライブを戻さないまま処理を続けます");
  766.             w_wait(300);
  767. //            w_close();
  768.             ret = -1;
  769.         } else {
  770. #if 0
  771.             w_open();
  772.             w_mes(0, "CHGDRV:");
  773.             w_mes(1, "ドライブを移動前に戻しました");
  774.             w_wait(20);
  775. //            w_close();
  776. #endif
  777.         }
  778.     }
  779.  
  780.     return ret;
  781. }
  782.  
  783.  
  784.  
  785. /*
  786.     指定ドライブ('A'~'Z')の準備ができていなかったら、
  787.     準備を促すメッセージを出して準備待ちする。
  788.     右クリックで中断。
  789.  
  790.     戻り値:0    OK
  791.         1    中断
  792. */
  793. static int
  794. chk_drvready(char drv, const char *msg)
  795. {
  796.     if (!drvready(drv)) {
  797.         char bf[96];
  798.         w_open();
  799.         sprintf(bf, "ドライブ %C: の準備ができていません", drv);
  800.         w_mes(0, msg);
  801.         w_mes(1, bf);
  802.         w_mes(2, "ドライブの用意をして下さい(右クリックで中止)");
  803.         while (!drvready(drv)) {
  804.             int dmx, dmy, bl, br;
  805.             dmsstat(&dmx, &dmy, &bl, &br);
  806.             if (br) {
  807.                 wait_mb_off();
  808.                 w_close();
  809.                 return 1;
  810.             }
  811.         }
  812.     }
  813.  
  814.     return 0;
  815. }
  816.